home *** CD-ROM | disk | FTP | other *** search
- ;CALCFFP.ASM BY DANIEL WOLF 02/18/89
- ;WITH FLOATING POINT (FFP SINGLE PRECISION) CONVERSION ROUTINES BY DANIEL WOLF
- ;COPYRIGHT 1989 BY DANIEL WOLF Ph.D.
-
- LVO.SPFIX EQU $FFFFFFE2 ; -30
- LVO.SPFLT EQU $FFFFFFDC ; -36
- LVO.SPCMP EQU $FFFFFFD6 ; -42
- LVO.SPTST EQU $FFFFFFD0 ; -48
- LVO.SPABS EQU $FFFFFFCA ; -54
- LVO.SPNEG EQU $FFFFFFC4 ; -60
- LVO.SPADD EQU $FFFFFFBE ; -66
- LVO.SPSUB EQU $FFFFFFB8 ; -72
- LVO.SPMUL EQU $FFFFFFB2 ; -78
- LVO.SPDIV EQU $FFFFFFAC ; -84
-
- LVO.OUTPUT EQU $FFFFFFC4 ; -60
- LVO.WRITE EQU $FFFFFFD0 ; -48
-
- LVO.OPENLIBRARY EQU $FFFFFDD8 ; -552
- LVO.CLOSELIBRARY EQU $FFFFFE62 ; -414
-
-
- MAIN
- MOVE.L A0,A5 ;SAVE POINTER TO THE ASCII #S TYPED IN
- MOVE.L $4,A6 ;USE FIXED EXECBASE POINTER
-
- LEA DOSNAME,A1 ;OPEN DOS LIBRARY
- CLR.L D0
- JSR LVO.OPENLIBRARY(A6)
- MOVE.L D0,A4 ;SAVE ITS BASE ADDRESS
- BEQ QUIT2
-
- LEA MATHNAME,A1 ;OPEN MATH LIBRARY
- CLR.L D0
- JSR LVO.OPENLIBRARY(A6)
- MOVE.L D0,A3 ;SAVE ITS BASE AS WELL
- BEQ QUIT1
-
- MOVE.L A5,A0 ;NOW GET THE FIRST #
- BSR ASCTOFFP ;CONVERT TO FFP FORMAT
- BNE QUIT0
- MOVE.L D0,D6
-
- MOVE.L A5,A0 ;POINT A0 TO NEXT NUMBER
- MOVE.B -(A5),D7 ;KEEP OPERATOR IN D7
- BSR ASCTOFFP ;CONVERT 2ND # TO FFP
- BNE QUIT0
-
- MOVE.L D6,D1
- EXG D0,D1
-
- CMPI.B #'*',D7
- BEQ MULTIPLYEM
- CMPI.B #'/',D7
- BEQ DIVIDEM
- CMPI.B #'-',D7
- BEQ SUBTRACTEM
-
- ADDEM
- JSR LVO.SPADD(A3)
-
- FFPTOASC ;CONVERT RESULT IN D0 BACK TO ASCII
- LEA DECBUF2,A0 ;ROUTINE GOOD FOR UP TO 16 DIGITS TOTAL ACCURACY
- BTST.L #7,D0 ;IS THE FFP # NEGATIVE?
- BEQ POSITIVEFFP
- MOVE.B #'-',(A0) ;YES, PUT NEG SIGN INTO ASCII BUFFER
- POSITIVEFFP
- BCLR.L #7,D0 ;WORK WITH IT AS POSITIVE
- ADDA.L #1,A0
- MOVE.L D0,D7 ;HIDE IT IN D7
- MOVE.L #$BEBC205B,D6 ;FIRST POWER OF 10 IS 10^8
- MOVE.W #16,D4 ;MAX POWER OF 10 DIVIDES
- DIVPOWEROFTEN
- TST.W D4
- BEQ ENDFFPTDA
- SUBQ.W #1,D4 ;DEC POWER OF 10 BY 1
- ADDA.L #1,A0 ;ADVANCE POINTER BY 1
- CMPI.W #7,D4
- BNE NOTDECPOINT
- MOVE.B #'.',(A0)+
- MOVE.L #$CCCCCC3D,D0 ;ONE TENTH IN FFP NOTATION
- BRA PASTDECPOINT
- NOTDECPOINT
- MOVE.L D6,D0 ;BRING CURRENT POWER OF 10 INTO D0
- MOVE.L #$A0000044,D1 ;DIVIDE BY 10 IN FFP NOTATION
- JSR LVO.SPDIV(A3)
- PASTDECPOINT
- MOVE.B #'0',(A0) ;ZERO THIS SPOT IN THE BUFFER
- MOVE.L D0,D1 ;PUT POWER OF 10 INTO D1
- MOVE.L D0,D6 ;SAVE POWER OF 10 IN D6
- MOVE.L D7,D0 ;PUT CURRENT VALUE OF FFP NUMBER INTO D0
- COMPWITHPOWER
- JSR LVO.SPCMP(A3) ;COMPARE POWER OF 10 WITH FFP NUMBER - TRASHES REGS!
- BLT DIVPOWEROFTEN
- SUBPOWEROFTEN
- MOVE.L D7,D0 ;FFP # INTO D0
- MOVE.L D6,D1 ;POWER INTO D1
- JSR LVO.SPSUB(A3)
- MOVE.L D0,D7 ;SAVE CURRENT VALUE OF FFP NUMBER
- ADD.B #1,(A0) ;ADD 1 TO THE DIGIT AT THIS POWER OF 10
- BRA COMPWITHPOWER
- ENDFFPTDA
-
- STRIP ;STRIP LEADING ZEROS IN THE ASCII BUFFER
- LEA DECBUF2+1,A0
- STRIPMORE
- MOVE.B (A0),D0
- CMPI.B #'0',D0
- BNE NOWRITE
- MOVE.B #' ',(A0)+
- BRA STRIPMORE
- NOWRITE
- JSR LVO.OUTPUT(A4) ;GRAB THE OUTPUT FILE HANDLE FOR THIS CLI
- MOVE.L D0,D1
- MOVE.L #DECBUF,D2 ;DECBUF HAS THE ASCII RESULT OF OPERATION
- MOVE.L #23,D3
- JSR LVO.WRITE(A4) ;WRITE OUT THE ASCII RESULT
- QUIT0
- MOVE.L A3,A1 ;CLOSE DOWN LIBRARIES
- JSR LVO.CLOSELIBRARY(A6)
- QUIT1
- MOVE.L A4,A1
- JSR LVO.CLOSELIBRARY(A6)
- QUIT2 ;AND HOME, JEEVES.
- RTS
-
- DIVIDEM
- JSR LVO.SPDIV(A3)
- BRA FFPTOASC
- MULTIPLYEM
- JSR LVO.SPMUL(A3)
- BRA FFPTOASC
- SUBTRACTEM
- JSR LVO.SPSUB(A3)
- BRA FFPTOASC
-
-
- ASCTOFFP ;SUBROUTINE TO CONVERT ASCII TO FFP NOTATION
- ;ENTER W/ A0 POINTING TO ASCII DECIMAL TEXT
- ;EXIT WITH FFP NUMBER IN D0
- ;ERROR INDICATOR IS D1 - 0 MEANS OK
- ; 1 MEANS ERROR
- CLR.L D5
- CMPI.B #'-',(A0) ;IS IT A NEGATIVE NUMBER?
- BNE.S CONVERTPOS
- MOVE.B #128,D5 ;YES, SET UP SIGN BIT FOR CORRECTION TO RESULT
- ADDA.L #1,A0 ;AND MOVE ADDRESS POINTER BEYOND THE NEG SIGN
-
- CONVERTPOS ;CONVERT POSITIVE ASCII DECIMAL TO BINARY NUMBER
- CLR.L D0 ;REGISTER TO ACCUMULATE THE BINARY CONVERSION
- CLR.L D2
- CLR.L D4
- GETDIG
- MOVE.B (A0)+,D3 ;GET ASCII DECIMAL DIGIT BYTE
- CMPI.B #'.',D3 ;HIT THE DP?
- BNE TESTDIG ;NOPE, GO ON
- MOVEQ #1,D4 ;YUP, SET RIGHT OF DP FLAG AND GRAB ANOTHER DIGIT
- CLR.L D2
- BRA GETDIG
- TESTDIG
- CMPI.B #'9',D3 ;CHECK THAT IT IS REALLY AN ASCII DECIMAL DIGIT
- BHI.S NOMORE ;IF NOT A DIGIT, MOVE ON
- CMPI.B #'0',D3
- BLT.S NOMORE ;IF NOT A DIGIT, MOVE ON
- ANDI.L #$0F,D3 ;STRIP DOWN TO 4 BITS (STRIP THE ASCII)
-
- LSL.L #1,D0 ;MULTIPLY EXISTING BINARY NUMBER BY 10
- MOVE.L D0,D1 ;FIRST DOUBLE, THEN DOUBLE TWICE MORE AND ADD
- LSL.L #2,D0 ;THATS THE SAME AS 2X + 8X
- ADD.L D1,D0
- ADD.L D3,D0 ;AND ADD IN THE NEW DECIMAL DIGIT
-
- ADDQ.B #1,D2 ;INC # OF DIGITS EITHER SIDE OF DP
- CMPI.B #8,D2 ;REACHED 8 (THE MAXIMUM HERE)?
- BNE.S GETDIG ;NO, GET ANOTHER ASCII DECIMAL DIGIT
- FFPERR
- MOVEQ #1,D1
- RTS
-
- NOMORE
- MOVE.L A0,A5 ;SAVE POINTER TO NEXT #
- JSR LVO.SPFLT(A3) ;MAKE THIS # INTO FLOATING POINT
- TST.L D4
- BEQ JUSTLEFT ;SKIP FRACTIONIZING IF THERES NO FRACTION
- SUBQ.L #1,D2
- BMI.S JUSTLEFT
- FRACTIONIZE ;DIVIDE BY 10 ONCE FOR EACH DIGIT RIGHT OF THE DP
- MOVE.L #$A0000044,D1
- JSR LVO.SPDIV(A3)
- DBRA D2,FRACTIONIZE ;D2 IS THE DIGIT COUNT FOR THE FRACTIONAL PART
- JUSTLEFT
- EOR.L D5,D0 ;SET THE SIGN
- CLR.L D1 ;NO ERROR
- RTS
-
- DATA
-
- CNOP 0,4 ;ALIGN TO LONGWORD
-
- DECBUF ;THIS IS TRICKY
- DC.B 10,' ' ;START WITH LINEFEED AND SPACE
- DECBUF2
- DC.B ' 0' ;ROOM FOR NEG SIGN AND FIRST 0
- MATHNAME
- DC.B 'mathffp.library' ;THIS AREA USED AS PART OF DECBUF, ALSO!!
- DC.B 0,10,10,10 ;A FEW LINEFEEDS
- EVEN
- DOSNAME
- DC.B 'dos.library',0
- EVEN
-
- END
-
-